﻿// api.js - 封装API请求函数

const app = getApp()

// 获取全局应用实例
const getAppInstance = () => {
  return getApp();
};

// 获取API基础URL
const getBaseUrl = () => {
  return getAppInstance().globalData.baseUrl;
};

// 获取请求头
const getHeaders = () => {
  const token = getAppInstance().globalData.token;
  return {
    'Content-Type': 'application/json',
    'Authorization': token ? `Bearer ${token}` : ''
  };
};

// client_token存储
let clientToken = null;
let clientTokenExpireTime = 0;

// ---- 新增状态变量 ----
let isFetchingFixedToken = false; // 标记是否正在获取fixed token
const fixedTokenFetchCooldownMs = 5000; // 获取fixed token失败后的冷却时间（毫秒）
let lastFixedTokenFetchFailedTimestamp = 0; // 上次获取fixed token失败的时间戳
// ---- 状态变量结束 ----

// 通用请求方法
function request(url, method, data, needAuth = true) {
  console.log(`发起${method}请求: ${url}`);
  
  return new Promise((resolve, reject) => {
    // 构建请求头
    const header = {
      'content-type': 'application/json',
      'x-api-key': 'qsmhsecureapikey20240601' // 使用服务器配置的 API Key
    };
    
    // 添加授权头（如有token）
    if (needAuth) {
      // 在无需登录模式下，不添加用户token，但必要时使用client_token
      if (app.globalData.skipLoginMode) {
        if (clientToken) {
          // 确保token没有无效字符
          const cleanToken = clientToken.replace(/[^\x20-\x7E]/g, '');
          header.Authorization = `Bearer ${cleanToken}`;
          console.log('使用client_token进行API授权');
        }
      } else if (app.globalData.token) {
        // 确保token没有无效字符
        const cleanToken = app.globalData.token.replace(/[^\x20-\x7E]/g, '');
        header.Authorization = `Bearer ${cleanToken}`;
        console.log('使用用户token进行API授权');
      }
    }
    
    // 如果url不是完整URL，则添加baseUrl
    if (!url.startsWith('http')) {
      url = app.globalData.apiBaseUrl + url;
    }
    
    // 发起请求
    tt.request({
      url: url,
      method: method,
      data: data,
      header: header,
      success(res) {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          // 请求成功
          console.log(`API请求成功: ${url}`, res.data);
          resolve(res.data);
        } else {
          // 请求失败
          console.error(`API请求失败: ${url}, 状态码: ${res.statusCode}`, res.data);
          
          // 特殊处理401错误（未授权）
          if (res.statusCode === 401) {
            // ---- 修改401处理逻辑 ----
            // 在无需登录模式下，尝试获取fixed-token，但增加并发和冷却控制
            if (app.globalData.skipLoginMode) {
              const now = Date.now();
              // 检查是否已在获取或处于冷却期
              if (isFetchingFixedToken) {
                console.log('获取固定token的操作正在进行中，跳过此次尝试');
                reject(new Error('Token获取中，请稍后重试')); 
                return;
              }
              if (now - lastFixedTokenFetchFailedTimestamp < fixedTokenFetchCooldownMs) {
                console.log('获取固定token的操作处于失败冷却期，跳过此次尝试');
                reject(new Error('Token获取失败冷却中，请稍后重试'));
                return;
              }

              // 设置标记，开始获取token
              isFetchingFixedToken = true;
              console.log('无需登录模式: 尝试获取固定token');
              module.exports.getFixedToken()
                .then(() => {
                  isFetchingFixedToken = false; // 成功后重置标记
                  lastFixedTokenFetchFailedTimestamp = 0; // 成功后重置失败时间戳
                  // 刷新token成功后，重试原请求
                  console.log('刷新token成功，重试原请求');
                  module.exports.request(url, method, data, needAuth)
                    .then(resolve)
                    .catch(reject);
                })
                .catch((tokenErr) => {
                  isFetchingFixedToken = false; // 失败后重置标记
                  lastFixedTokenFetchFailedTimestamp = Date.now(); // 记录失败时间戳
                  console.error('刷新token失败', tokenErr);
                  // 失败时不再自动重试，直接拒绝原请求
                  reject(new Error('获取固定token失败，请检查网络或API Key配置')); 
                });
              return; // 结束处理
            }
            // ---- 401处理逻辑修改结束 ----
            
            // 标准模式下清除登录信息
            app.clearLoginInfo();
            reject(res.data); // 拒绝原请求
            return; // 增加 return 明确结束
          }
          
          // 非401错误，直接拒绝
          reject(res.data);
        }
      },
      fail(err) {
        console.error(`API请求网络错误: ${url}`, err);
        reject(err);
      }
    });
  });
}

// 获取应用级别client_token
const getClientToken = () => {
  // 检查是否有有效的客户端token
  if (clientToken && clientTokenExpireTime > Date.now()) {
    console.log('使用缓存的client_token');
    return Promise.resolve(clientToken);
  }
  
  // 请求新的client_token
  console.log('请求新的client_token');
  return request('/api/client-token', 'GET', null, false)
    .then(res => {
      console.log('获取client_token响应:', res);
      
      // 尝试从不同的位置获取token
      let token = null;
      
      // 1. 检查标准位置
      if (res.client_token) {
        token = res.client_token;
      }
      // 2. 检查token字段
      else if (res.token) {
        token = res.token;
      }
      // 3. 检查data.token字段
      else if (res.data && res.data.token) {
        token = res.data.token;
      }
      // 4. 检查access_token字段
      else if (res.access_token) {
        token = res.access_token;
      }
      // 5. 如果服务器直接返回了字符串
      else if (typeof res === 'string' && res.length > 10) {
        token = res;
      }
      // 6. 如果响应是简单对象并且只有一个属性，尝试使用它
      else if (typeof res === 'object' && Object.keys(res).length === 1) {
        const firstKey = Object.keys(res)[0];
        const firstValue = res[firstKey];
        if (typeof firstValue === 'string' && firstValue.length > 10) {
          token = firstValue;
        }
      }
      
      // 如果成功找到token
      if (token) {
        clientToken = token;
        // 设置过期时间（默认7200秒，提前5分钟过期）
        const expiresIn = (res.expires_in || 7200) - 300;
        clientTokenExpireTime = Date.now() + expiresIn * 1000;
        
        console.log(`获取client_token成功, ${expiresIn}秒后过期`);
        return clientToken;
      } else {
        // 创建一个临时token用于调试
        console.warn('未能从响应中提取token，创建临时token');
        clientToken = 'temp_token_' + Date.now();
        clientTokenExpireTime = Date.now() + 300 * 1000; // 5分钟后过期
        return clientToken;
      }
    })
    .catch(err => {
      console.error('获取client_token请求失败:', err);
      throw err;
    });
};

// 获取固定token (用于无需登录模式下的应急情况)
const getFixedToken = () => {
  console.log('请求固定token');
  return request('/api/fixed-token', 'GET', null, false)
    .then(res => {
      console.log('获取固定token响应:', res);
      
      // 尝试从不同的位置获取token
      let token = null;
      
      // 1. 检查标准位置
      if (res.client_token) {
        token = res.client_token;
      }
      // 2. 检查token字段
      else if (res.token) {
        token = res.token;
      }
      // 3. 检查data.token字段
      else if (res.data && res.data.token) {
        token = res.data.token;
      }
      // 4. 检查access_token字段
      else if (res.access_token) {
        token = res.access_token;
      }
      // 5. 如果服务器直接返回了字符串
      else if (typeof res === 'string' && res.length > 10) {
        token = res;
      }
      // 6. 如果响应是简单对象并且只有一个属性，尝试使用它
      else if (typeof res === 'object' && Object.keys(res).length === 1) {
        const firstKey = Object.keys(res)[0];
        const firstValue = res[firstKey];
        if (typeof firstValue === 'string' && firstValue.length > 10) {
          token = firstValue;
        }
      }
      
      // 如果成功找到token
      if (token) {
        clientToken = token;
        // 设置过期时间（默认7200秒，提前5分钟过期）
        const expiresIn = (res.expires_in || 7200) - 300;
        clientTokenExpireTime = Date.now() + expiresIn * 1000;
        
        console.log(`获取固定token成功, ${expiresIn}秒后过期`);
        return clientToken;
      } else {
        // 创建一个临时token用于调试
        console.warn('未能从响应中提取固定token，创建临时token');
        clientToken = 'fixed_temp_token_' + Date.now();
        clientTokenExpireTime = Date.now() + 300 * 1000; // 5分钟后过期
        return clientToken;
      }
    })
    .catch(err => {
      console.error('获取固定token请求失败:', err);
      throw err;
    });
};

// 使用client_token进行API请求（不需要用户授权的接口）
function requestWithClientToken(url, method, data = {}) {
  return new Promise((resolve, reject) => {
    getClientToken() // 获取 clientToken
      .then(token => {
        // 确保token没有无效字符
        const cleanToken = token.replace(/[^\x20-\x7E]/g, '');
        
        // 准备实际请求的 URL
        let requestUrl = url;
        if (!requestUrl.startsWith('http')) {
          requestUrl = app.globalData.apiBaseUrl + requestUrl;
        }
        
        console.log(`使用 client_token 发起 ${method} 请求: ${requestUrl}`);
        
        tt.request({
          url: requestUrl,
          method: method,
          data: data,
          header: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${cleanToken}`, // 使用清理过的 clientToken
            'x-api-key': 'qsmhsecureapikey20240601'   // <--- 确保这里是正确的 API Key
          },
          success: (res) => {
            if (res.statusCode >= 200 && res.statusCode < 300) {
              console.log(`使用 client_token 请求成功: ${url}`, res.data);
              resolve(res.data);
            } else {
              console.error(`使用 client_token 请求失败 ${url}:`, res);
              reject(new Error(res.data?.message || `请求失败，状态码: ${res.statusCode}`));
            }
          },
          fail: (err) => {
            console.error(`使用 client_token 请求错误 ${url}:`, err);
            reject(err);
          }
        });
      })
      .catch(err => {
        console.error('获取client_token失败，无法完成请求:', err);
        reject(err); // 如果获取 clientToken 失败，也拒绝请求
      });
  });
}

// 基础请求函数 - GET
function get(url) {
  return new Promise((resolve, reject) => {
    // 如果没有token，则拒绝请求
    if (!app.globalData.token) {
      reject(new Error('用户未登录'))
      return
    }
    
    // 确保token没有无效字符
    const cleanToken = app.globalData.token.replace(/[^\x20-\x7E]/g, '');
    
    tt.request({
      url: `${app.globalData.apiBaseUrl}${url}`,
      method: 'GET',
      header: {
        'Authorization': `Bearer ${cleanToken}`
      },
      success: (res) => {
        if (res.statusCode === 200) {
          resolve(res.data)
        } else {
          reject(new Error(res.data.message || '请求失败'))
        }
      },
      fail: (err) => {
        reject(err)
      }
    })
  })
}

// 基础请求函数 - POST
function post(url, data) {
  return new Promise((resolve, reject) => {
    // 登录接口不需要token
    const needToken = !url.includes('/login') && !url.includes('/api/user/login')
    
    // 如果需要token但没有，则拒绝请求
    if (needToken && !app.globalData.token) {
      console.error(`请求需要token但未登录: ${url}`);
      reject(new Error('用户未登录'))
      return
    }
    
    const header = {
      'Content-Type': 'application/json'
    }
    
    // 如果需要token，添加到请求头
    if (needToken) {
      // 确保token没有无效字符
      const cleanToken = app.globalData.token.replace(/[^\x20-\x7E]/g, '');
      header['Authorization'] = `Bearer ${cleanToken}`
    }
    
    // 对登录请求进行特殊处理
    if (url.includes('/login')) {
      console.log('处理登录请求，发送数据:', JSON.stringify(data));
    }
    
    console.log(`发起POST请求: ${url}, 数据:`, data);
    
    tt.request({
      url: `${app.globalData.apiBaseUrl}${url}`,
      method: 'POST',
      header: header,
      data: data,
      success: (res) => {
        console.log(`POST请求成功: ${url}`, res.data)
        if (res.statusCode === 200) {
          resolve(res.data)
        } else {
          console.error(`POST请求失败: ${url}`, res.statusCode, res.data)
          reject(new Error(res.data?.message || '请求失败'))
        }
      },
      fail: (err) => {
        console.error(`POST请求错误: ${url}`, err)
        reject(err)
      }
    })
  })
}

// 获取用户任务列表
function getUserTasks(page = 1, limit = 10) {
  return get(`/api/user/tasks?page=${page}&limit=${limit}`)
}

// 获取单个任务详情
function getTaskDetail(taskId) {
  return get(`/api/tasks/${taskId}`)
}

// 获取会员套餐列表
function getVipPackages() {
  return get('/api/vip/packages')
}

// 购买会员
function purchaseVip(packageId, paymentMethod) {
  return post('/api/vip/purchase', {
    packageId: packageId,
    paymentMethod: paymentMethod
  })
}

// 获取积分套餐列表
function getCreditPackages() {
  return get('/api/credits/packages')
}

// 购买积分
function purchaseCredits(packageId, paymentMethod) {
  return post('/api/credits/purchase', {
    packageId: packageId,
    paymentMethod: paymentMethod
  })
}

// 提交画图任务
const generateImage = (prompt, aspectRatio = '1:1') => {
  return new Promise((resolve, reject) => {
    const app = getAppInstance();
    
    // 检查是否有足够积分或免费次数
    const credits = app.globalData.credits || 0;
    const freeCredits = app.globalData.freeCredits || 0;
    
    // 检查积分或免费次数是否足够
    if (credits <= 0 && freeCredits <= 0) {
      return reject(new Error('积分和免费次数不足，请充值或观看广告获取'));
    }
    
    post('/advanced-generation/generate', {
      prompt,
      aspectRatio
    }).then(res => {
      if (res.success && res.taskId) {
        // 保存当前任务ID到本地
        tt.setStorageSync('currentTaskId', res.taskId);
        
        // 开始轮询任务状态
        startPollingTask(res.taskId);
        
        resolve(res);
      } else {
        reject(new Error(res.message || '提交任务失败'));
      }
    }).catch(reject);
  });
};

// 开始轮询任务状态
const startPollingTask = (taskId) => {
  const app = getAppInstance();
  app.pollTaskStatus(taskId);
};

// 获取任务状态
const getTaskStatus = (taskId) => {
  return get(`/api/tasks/${taskId}`);
};

// 获取用户信息
const getUserInfo = () => {
  return get('/api/user/info');
};

// 获取用户积分
const getUserCredits = () => {
  return get('/api/user/credits');
};

// 用户签到
const checkIn = () => {
  return post('/api/user/checkIn');
};

// 取消任务
const cancelTask = (taskId, reason = '用户取消') => {
  return post('/api/cancelTask', { taskId, reason });
};

// 观看广告获取积分
const watchAdForCredits = () => {
  return post('/api/user/watchAd');
};

// =========== 使用 client_token 的API功能 ===========

// 获取平台热门话题（不需要用户登录）
const getHotTopics = () => {
  return requestWithClientToken('/api/platform/hot-topics', 'GET');
};

// 获取平台推荐内容（不需要用户登录）
const getRecommendContent = (limit = 10) => {
  return requestWithClientToken('/api/platform/recommend', 'GET', { limit });
};

// 获取公共模板和样式（不需要用户登录）
const getPublicTemplates = (category = 'all') => {
  return requestWithClientToken('/api/platform/templates', 'GET', { category });
};

// 获取系统公告（不需要用户登录）
const getSystemAnnouncements = () => {
  return requestWithClientToken('/api/platform/announcements', 'GET');
};

// 获取生成示例（不需要用户登录）
const getGenerationExamples = () => {
  return requestWithClientToken('/api/platform/examples', 'GET');
};

// 创建画图请求方法
const createDrawing = (prompt, options = {}) => {
  console.log('发起创建画图请求');
  
  // 构建请求数据
  const requestData = {
    prompt: prompt,
    ...options
  };
  
  // 添加匿名用户信息（无需登录模式）
  if (app.globalData.skipLoginMode && app.globalData.userInfo) {
    requestData.anonymousUser = {
      nickName: app.globalData.userInfo.nickName,
      credits: app.globalData.userInfo.credits
    };
  }
  
  return request('/api/drawing/create', 'POST', requestData);
};

// 查询画图结果
const queryDrawingResult = (taskId) => {
  return request(`/api/drawing/result?taskId=${taskId}`, 'GET')
    .then(res => {
      // 处理返回结果中的相对路径图片URL
      if (res && res.imageUrl) {
        res.imageUrl = ensureFullUrl(res.imageUrl);
      }
      return res;
    });
};

// 处理相对路径URL，转换为完整URL
const ensureFullUrl = (url) => {
  if (!url) return url;
  if (url.startsWith('/')) {
    return `${app.globalData.apiBaseUrl}${url}`;
  }
  return url;
};

// 放大图片
const upscaleImage = (taskId, index) => {
  console.log(`调用放大图片API: 任务ID=${taskId}, 索引=${index}`);
  // 确保索引是整数并在1-4的范围内
  const validIndex = parseInt(index);
  if (isNaN(validIndex) || validIndex < 1 || validIndex > 4) {
    return Promise.reject(new Error(`无效的索引值: ${index}，必须是1-4之间的整数`));
  }
  
  // 改为直接调用MJ API的/mj/submit/change接口
  const apiUrl = '/api/drawing/upscale'; // 保持原有接口不变，服务器将正确转发
  
  // 按照MJ API规范构造请求体
  return request(apiUrl, 'POST', {
    taskId: taskId,
    index: validIndex,
    // 增加action参数，指明是放大操作
    action: "UPSCALE"
  });
};

// 创建变体
const createVariation = (taskId, index) => {
  console.log(`调用创建变体API: 任务ID=${taskId}, 索引=${index}`);
  // 确保索引是整数并在1-4的范围内
  const validIndex = parseInt(index);
  if (isNaN(validIndex) || validIndex < 1 || validIndex > 4) {
    return Promise.reject(new Error(`无效的索引值: ${index}，必须是1-4之间的整数`));
  }
  
  // 改为直接调用MJ API的/mj/submit/change接口
  const apiUrl = '/api/drawing/variation'; // 保持原有接口不变，服务器将正确转发
  
  // 按照MJ API规范构造请求体
  return request(apiUrl, 'POST', {
    taskId: taskId,
    index: validIndex,
    // 增加action参数，指明是变体操作
    action: "VARIATION"
  });
};

// 使用DeepSeek API翻译中文提示词为英文
const translatePromptWithDeepSeek = (chinesePrompt) => {
  console.log('开始调用DeepSeek API翻译提示词:', chinesePrompt);
  
  // 构建请求数据
  const requestData = {
    model: "deepseek-chat",
    messages: [
      {
        role: "user", 
        content: `你是一位专业的Midjourney提示词专家。请将以下中文提示词翻译成适合Midjourney使用的英文提示词，要求：

1. 遵循Midjourney提示词最佳实践，使用简洁关键词组合而非完整句子
2. 添加适当的艺术风格、摄影、光照等专业术语增强效果
3. 使用逗号分隔不同概念，添加合适的修饰词丰富细节
4. 保持提示词的主要意图和描述对象不变
5. 仅返回翻译的英文提示词，不要解释或添加任何其他内容
6. 不要使用markdown格式
7. 对于人物描述，优化为"beautiful female, 20 years old"这种关键词组合格式

中文提示词：${chinesePrompt}

注意：直接返回Midjourney格式的英文提示词，不要包含任何解释、前缀或其他内容。`
      }
    ],
    temperature: 0.3
  };
  
  // 定义API密钥 - 用户需要替换为自己的有效密钥
  const apiKey = "sk-d2616b2beb524c3982695235a13d20e9"; // 示例密钥，请替换为实际有效的DeepSeek API密钥
  
  console.log('正在调用DeepSeek翻译API...');
  
  // 调用DeepSeek API
  return new Promise((resolve, reject) => {
    tt.request({
      url: 'https://api.deepseek.com/v1/chat/completions',
      method: 'POST',
      data: requestData,
      header: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${apiKey}`
      },
      success(res) {
        // 检查响应是否成功
        if (res.statusCode >= 200 && res.statusCode < 300 && res.data) {
          try {
            console.log('DeepSeek API响应:', res.data);
            
            // 从响应中提取翻译结果
            const translatedText = res.data.choices[0].message.content.trim();
            console.log('翻译结果:', translatedText);
            
            resolve({
              success: true,
              translatedPrompt: translatedText,
              originalPrompt: chinesePrompt
            });
          } catch (error) {
            console.error('处理DeepSeek响应出错:', error);
            reject({
              success: false,
              error: '处理翻译结果失败',
              details: error.message
            });
          }
        } else {
          console.error('DeepSeek API请求失败:', res.statusCode, res.data);
          reject({
            success: false,
            error: `API请求失败: ${res.statusCode}`,
            details: res.data
          });
        }
      },
      fail(err) {
        console.error('DeepSeek API网络请求失败:', err);
        reject({
          success: false,
          error: '网络请求失败',
          details: err
        });
      }
    });
  });
};

// 导出API函数
module.exports = {
  get,
  post,
  generateImage,
  getUserTasks,
  getTaskDetail,
  getVipPackages,
  purchaseVip,
  getCreditPackages,
  purchaseCredits,
  getTaskStatus,
  getUserInfo,
  getUserCredits,
  checkIn,
  cancelTask,
  watchAdForCredits,
  getAppInstance,
  getClientToken,
  requestWithClientToken,
  getHotTopics,
  getRecommendContent,
  getPublicTemplates,
  getSystemAnnouncements,
  getGenerationExamples,
  createDrawing,
  queryDrawingResult,
  getFixedToken,
  ensureFullUrl,
  upscaleImage,
  createVariation,
  translatePromptWithDeepSeek
};